using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace Tron.Animations
{
    public abstract class Animation
    {
        bool finished;
        double duration;
        float progress;
        float smoothProgress;
        double elapsedTime;
        double startTime;
        double overflowRecieved = 0;

        public bool Finished { get { return finished; } }
        public double Duration { get { return duration; } }
        public float Progress { get { return progress; } }
        public float SmoothProgress { get { return smoothProgress; } }
        public double ElapsedTime { get { return elapsedTime; } }
        public double Overflow { get { return Math.Max(elapsedTime - duration, 0); } }
        public double TimeLeft { get { return Math.Max(duration - elapsedTime, 0); } }
        public void GiveOverflow(double value)
        {
            overflowRecieved = value;
        }

        protected void Recycle(double duration)
        {
            this.duration = duration;
            finished = false;
        }

        protected Animation(double duration)
        {
            this.duration = duration;
        }

        public virtual void Initialize(GameTime gameTime)
        {
            this.startTime = gameTime.TotalGameTime.TotalSeconds - overflowRecieved;
        }

        public virtual void Update(GameTime gameTime)
        {
            if (duration <= 0)
            {
                progress = 1;
                smoothProgress = 1;
                finished = true;
                return;
            }

            double currentTime = gameTime.TotalGameTime.TotalSeconds;
            elapsedTime = currentTime - startTime;

            progress = MathHelper.Clamp(
                (float)(elapsedTime / duration),
                0, 1);

            smoothProgress = MathHelper.SmoothStep(0, 1, progress);

            if (progress == 1)
                finished = true;
        }

        public virtual void Finish() { }

        #region Converters - Converter<Animation, T>
        protected static double DurationOfAnimation(Animation animation)
        {
            return animation.duration;
        } 
        #endregion
    }
}